using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;


// 一个工具类
static class EncodeTools
{
    #region 解决tcp运输时的粘包和拆包问题
    public static byte[] EncodePacket(byte[] message)
    {
        MemoryStream ms = new MemoryStream();
        BinaryWriter writer = new BinaryWriter(ms);

        // 写入信息长度
        writer.Write(message.Length);
        // 写入信息本身
        writer.Write(message);
        byte[] resData = new byte[(int)ms.Length];
        Buffer.BlockCopy(ms.GetBuffer(), 0, resData, 0, (int)ms.Length);

        // 关闭数据流
        ms.Close();
        writer.Close();

        return resData;
    }

    public static byte[] DecodeMessage(ref List<byte> lt)
    {
        if(lt.Count < 4)
        {
            throw new Exception("数据不足4字节");
        }
        MemoryStream ms = new MemoryStream(lt.ToArray());
        BinaryReader reader = new BinaryReader(ms);

        int length = reader.ReadInt32();
        if((int)(ms.Length - ms.Position) < length)
        {
            return null;
            //throw new Exception("数据不全");
        }

        byte[] resData = new byte[length];
        resData = reader.ReadBytes(length);

        lt.Clear();
        lt.AddRange(reader.ReadBytes((int)(ms.Length - ms.Position)));

        ms.Close();
        reader.Close();

        return resData;
    }
    #endregion

    #region 构造发送的SocketMsg类
    /// <summary>
    /// 将SocketMsg中的信息解码出来
    /// </summary>
    public static byte[] EncodeMsg(SocketMsg msg)
    {
        MemoryStream ms = new MemoryStream();
        BinaryWriter writer = new BinaryWriter(ms);
        writer.Write(msg.OpCode);
        writer.Write(msg.SubCode);
        if(msg.Value != null)
        {
            byte[] valueBytes = EncodeObj(msg.Value);
            writer.Write(valueBytes);
        }
        byte[] resData = new byte[ms.Length];
        Buffer.BlockCopy(ms.GetBuffer(), 0, resData, 0, (int)ms.Length);

        writer.Close();
        ms.Close();

        return resData;
    }

    /// <summary>
    ///  将字节数组转化为SocketMsg对象供上层使用
    /// </summary>
    public static SocketMsg DecodeMsg(byte[] data)
    {
        MemoryStream ms = new MemoryStream(data);
        BinaryReader reader = new BinaryReader(ms);
        SocketMsg msg = new SocketMsg();
        msg.OpCode = reader.ReadInt32();
        msg.SubCode = reader.ReadInt32();

        if(ms.Length > ms.Position)
        {
            byte[] buff = reader.ReadBytes((int)(ms.Length - ms.Position));
            object value = DecodeObj(buff);
            msg.Value = value;
        }

        reader.Close();
        ms.Close();

        return msg;
    }

    internal static void EncodeMessage(byte[] data)
    {
        throw new NotImplementedException();
    }
    #endregion

    #region 将object对象进行序列化和反序列化

    /// <summary>
    ///  将obj对象序列化为byte数组返回
    /// </summary>
    public static byte[] EncodeObj(Object obj)
    {
        MemoryStream ms = new MemoryStream();
        BinaryFormatter bf = new BinaryFormatter();
        bf.Serialize(ms, obj);

        byte[] resData = new byte[ms.Length];
        Buffer.BlockCopy(ms.GetBuffer(), 0, resData, 0, (int)ms.Length);

        ms.Close();

        return resData;
    }

    /// <summary>
    /// 将byte数组反序列化为一个object对象供上层使用
    /// </summary>
    public static object DecodeObj(byte[] data)
    {
        MemoryStream ms = new MemoryStream(data);
        BinaryFormatter bf = new BinaryFormatter();
        object resObj = bf.Deserialize(ms);

        ms.Close();
        return resObj;
    }
    #endregion
}
